/*
 * basic_select application showing the basic generic usage of the dbConnect API
 * Copyright (C) 2002 Johnathan Ingram, jingram@rogueware.org
 *
 * This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
 *
 */


#include <iostream>
#include <map>
#include <string>

#include <time.h>

#include "dbconn/dbconnect.h"

using namespace std;


char *tf[] = {"false", "true"};

//basic_select 127.0.0.1 dbConnectDB root "" MYSQL TypeTest

int 
main(
      int argc, char** argv)
{   
   char sql[2048];
   map<string, DbConnection::Driver> drivers;

   drivers["MYSQL"] =       DbConnection::MYSQL;
   drivers["MSQL"] =        DbConnection::MSQL;
   drivers["POSTGRESQL"] =  DbConnection::POSTGRESQL;
   drivers["DB2"] =         DbConnection::DB2;

   if (argc == 7)
   {
      // Use smart pointers. Must be declared outside of the try
      //   as if an exception is caught it will loose scope and free. 
      DbConnectionVar driver;
      DbQueryVar conn;

      try
      {
         driver = new DbConnection(drivers[argv[5]]);

         // Print out the driver information.
         DbConnectionDriverInfo* info = driver->getDriverInformation();
         cout << "Author        : " << info->author << endl;
         cout << "Vendor        : " << info->vendor << endl;
         cout << "Copyright     : " << info->copyright << endl;
         cout << "Driver Type   : " << info->driverType << endl;
         cout << "Driver Name   : " << info->driverName << endl;
         cout << "Description   : " << info->driverDescription << endl;
         cout << "DbConnect Ver : " << info->dbConnectVersion << endl;
         cout << endl;

         // Connect to the database. 
         driver->connect(argv[3], argv[4], argv[2], argv[1]);
         // Get a query connection object
         conn = driver->requestQueryConnection();

         sprintf(sql, "SELECT * FROM %s", argv[6]);

         cout << "Using Query: " << sql << endl;
         conn->command(sql);
         conn->execute();

         // Output the infomation about the fields in the result set.
         if (!conn->fieldCount())
            cout << "No field information for this query" << endl;
         else
         {            
            // Note, can also use getFieldInfoByName function
            for(int i=0; i<conn->fieldCount(); i++)
            {
               if (conn->getFieldInfoByColumn(i)->isNotNull())
                  cout << "*";
               cout << conn->getFieldInfoByColumn(i)->name() << "\t";
            }
            cout << endl;
         }

         // Output the data in the result set
         cout << endl << endl;
         if (conn->eof())
            cout << "No rows in result set for this query" << endl;
         else
         {
            while (!conn->eof())
            {
               conn->fetchNext();

               // Note, can also use getFieldByName function
               for(int i=0; i<conn->fieldCount(); i++)
               {
                  if (conn->getFieldByColumn(i)->isNULL())
                     cout << "NULL" << "\t";
                  else
                     cout << conn->getFieldByColumn(i)->asString() << "\t";
               }
               cout << endl;                                  
            }
         }     
      }
      catch(BaseException &ex)
      {
         // Only need to catch a single exception. Can use name etc to determine the actual exception
         cout << "DbConnect Exception: " << ex.name << endl 
              << "  " << ex.code << " : " << ex.description << endl;
      }
      catch(...)
      {
         cout << "An Unknown exception has been trapped!\n" << endl;
      }
      cout << endl;
        
      // The 'conn' and 'driver' objects are smart pointers and will cleanup as soon as they go out of scope      
   }
   else
   {
      cout << "Syntax: basic_select HOST DATABASE USERNAME PASSWORD DRIVER TABLE" << endl;
      cout << "Drivers: MYSQL" << endl;
      cout << "       : MSQL" << endl;
      cout << "       : POSTGRESQL" << endl;
      cout << "       : DB2" << endl;
      return 1;
   }
   
   return 0;
}
